//
//  DPRunLoopSource.h
//  UITestingKit
//
//  Created by Ofri Wolfus on 09/02/07.
//  Copyright 2007 Ofri Wolfus. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>


/*!
 * @abstract A base class for runloop sources.
 * @discussion Subclass this class in order to create our own runloop source.
 */
@interface DPRunLoopSource : NSObject {
	@private
	CFRunLoopSourceRef _src;
}

/*!
 * @abstract Called by the runloop in order for the source to do its work.
 * @discussion Override this method in your subclass to perform the actual work.
 * The default implementation of this method does nothing.
 */
- (void)fire;

/*!
 * @abstract Signals the receiver, marking it as ready to fire.
 * @discussion This method marks the receiver as ready to fire.
 * The receiver's -fire will then be invoked by one of the runloops the receiver
 * is added to, whichever happens to be available first.
 * After firing, the receiver must be signaled again in order to fire again.
 */
- (void)signal;


/*!
 * @abstract Invalidates the receiver, stopping it from ever firing again.
 * @discussion Once invalidated, the receiver will never fire again. This method
 * automatically removes the receiver from all run loop modes in which it was registered.
 */
- (void)invalidate;

/*!
 * @abstract Returns whether the receiver is valid and able to fire.
 */
- (BOOL)isValid;


/*!
 * @abstract A scheduling callback for the receiver.
 * @discussion This method is invoked when the receiver is added to a run loop mode.
 * The default implementation of this method does nothing.
 */
- (void)scheduleWithRunLoop:(CFRunLoopRef)rl forMode:(NSString *)mode;

/*!
 * @abstract A cancel callback for the receiver.
 * @discussion This method is invoked when the receiver is removed from a run loop mode.
 * The default implementation of this method does nothing.
 */
- (void)cancelMode:(NSString *)mode forRunLoop:(CFRunLoopRef)rl;


/*!
 * @abstract Returns the underlying CFRunLoopSourceRef powering the receiver.
 */
- (CFRunLoopSourceRef)getCFRunLoopSource;

@end


/*!
 * @abstract Support for DPRunLoopSource.
 */
@interface NSRunLoop (DPRunLoopSource)

/*!
 * @abstract Registers <code>src</code> with the receiver for <code>mode</code>.
 */
- (void)addSource:(DPRunLoopSource *)src forMode:(NSString *)mode;

/*!
 * @abstract Unregisters <code>src</code> with the receiver for <code>mode</code>.
 */
- (void)removeSource:(DPRunLoopSource *)src forMode:(NSString *)mode;

/*!
 * @abstract Returns whether the receiver contains a given source.
 */
- (BOOL)containsSource:(DPRunLoopSource *)src inMode:(NSString *)mode;

@end
